package com.clarence.dada.modular.system.menu.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.clarence.dada.core.auth.context.LoginContext;
import com.clarence.dada.core.enums.ErrorEnum;
import com.clarence.dada.core.enums.StatusEnum;
import com.clarence.dada.core.enums.SymbolEnum;
import com.clarence.dada.core.enums.YesOrNotEnum;
import com.clarence.dada.core.exception.BusException;
import com.clarence.dada.core.exception.ServiceException;
import com.clarence.dada.core.tree.DefaultTreeBuildFactory;
import com.clarence.dada.modular.system.app.service.SysAppService;
import com.clarence.dada.modular.system.menu.entity.SysMenuEntity;
import com.clarence.dada.modular.system.menu.entity.SysMenuResourceEntity;
import com.clarence.dada.modular.system.menu.entity.req.SysMenuReq;
import com.clarence.dada.modular.system.menu.entity.resp.SysMenuDropDownTreeResp;
import com.clarence.dada.modular.system.menu.entity.resp.SysMenuResp;
import com.clarence.dada.modular.system.menu.entity.resp.SysMenuTreeResp;
import com.clarence.dada.modular.system.menu.factory.MenuFactory;
import com.clarence.dada.modular.system.menu.mapper.SysMenuMapper;
import com.clarence.dada.modular.system.menu.service.SysMenuButtonService;
import com.clarence.dada.modular.system.menu.service.SysMenuResourceService;
import com.clarence.dada.modular.system.menu.service.SysMenuService;
import com.clarence.dada.modular.system.role.service.SysRoleService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统菜单service接口实现类
 *
 * @author GD
 * @since 2020/3/13 16:05
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenuEntity> implements SysMenuService {

    @Lazy
    @Resource
    private SysMenuButtonService sysMenuButtonService;

    @Lazy
    @Resource
    private SysAppService sysAppService;

    @Resource
    private SysRoleService sysRoleService;

    @Resource
    private SysMenuResourceService sysMenuResourceService;

    @Override
    public void menuAdd(SysMenuReq req) {
        // 校验菜单名称是否重复
        validateMenu(req);
        // 父级节点处理
        if (req.getMenuParentId() == null) {
            // 如果父节点为空，则填充为默认的父节点id
            req.setMenuParentId(-1L);
        } else {
            // 如果父节点不为空，并且不是-1，则判断父节点存不存在，防止脏数据
            if (-1L != req.getMenuParentId()) {
                SysMenuReq tempParam = new SysMenuReq();
                tempParam.setMenuId(req.getMenuParentId());
                this.querySysMenu(tempParam);
            }
        }

        SysMenuEntity sysMenuEntity = new SysMenuEntity();
        BeanUtil.copyProperties(req, sysMenuEntity);
        // 组装pids
        String newPids = this.createPids(req.getMenuParentId());
        sysMenuEntity.setMenuPids(newPids);
        // 设置启用状态
        sysMenuEntity.setStatusFlag(StatusEnum.ENABLE.getCode());
        sysMenuEntity.setDelFlag(YesOrNotEnum.N.getCode());
        // 设置添加的菜单的类型
        if (ObjectUtil.isEmpty(sysMenuEntity.getVisible())) {
            sysMenuEntity.setVisible(YesOrNotEnum.N.getCode());
        }
        if (ObjectUtil.isNotEmpty(sysMenuEntity.getIcon()) || ObjectUtil.isNotEmpty(sysMenuEntity.getComponent())) {
            if (StrUtil.isEmpty(req.getVisible())) {
                sysMenuEntity.setVisible(YesOrNotEnum.Y.getCode());
            } else {
                sysMenuEntity.setVisible(req.getVisible());
            }
        }
        this.save(sysMenuEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void menuEdit(SysMenuReq req) {
        // 校验菜单名称是否重复
        validateMenu(req);
        // 获取库中的菜单信息
        SysMenuEntity oldMenu = this.querySysMenu(req);
        // 更新子节点以及子节点的子节点的appCode和层级关系（pids）
        String newPids = this.updateChildrenAppAndLevel(req, oldMenu);
        // 拷贝参数到实体中
        BeanUtil.copyProperties(req, oldMenu);
        // 设置新的pids
        oldMenu.setMenuPids(newPids);
        // 不能修改状态，用修改状态接口修改状态
        oldMenu.setStatusFlag(null);
        // 设置添加的菜单的类型
        if (oldMenu.getVisible() == null) {
            oldMenu.setVisible(YesOrNotEnum.N.getCode());
        }
        if (ObjectUtil.isNotEmpty(oldMenu.getIcon()) || ObjectUtil.isNotEmpty(oldMenu.getComponent())) {
            if (StrUtil.isEmpty(req.getVisible())) {
                oldMenu.setVisible(YesOrNotEnum.Y.getCode());
            } else {
                oldMenu.setVisible(req.getVisible());
            }
        }
        this.updateById(oldMenu);
    }

    @Override
    public SysMenuResp menuDetail(SysMenuReq req) {
        SysMenuEntity sysMenuEntity = this.querySysMenu(req);
        SysMenuResp sysMenuResp = Convert.convert(new TypeReference<>() {
        }, sysMenuEntity);

        // 设置父级菜单名称
        if (sysMenuResp != null) {
            Long menuParentId = sysMenuResp.getMenuParentId();
            if (-1L == menuParentId) {
                sysMenuResp.setMenuParentName("顶级");
            } else {
                Long parentId = sysMenuEntity.getMenuParentId();
                SysMenuEntity parentMenu = this.getById(parentId);
                if (parentMenu == null) {
                    sysMenuResp.setMenuParentName("无");
                } else {
                    sysMenuResp.setMenuParentName(parentMenu.getMenuName());
                }
            }
        }
        return sysMenuResp;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void menuDelete(SysMenuReq req) {
        // 获取所有子级的节点id
        LambdaQueryWrapper<SysMenuEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(SysMenuEntity::getMenuId)
                .eq(SysMenuEntity::getMenuId, req.getMenuId())
                .or()
                .eq(SysMenuEntity::getMenuParentId, req.getMenuId());
        List<SysMenuEntity> sysMenuEntitieList = this.getBaseMapper().selectList(wrapper);
        Set<Long> childIdList = sysMenuEntitieList.stream().map(SysMenuEntity::getMenuId).collect(Collectors.toSet());

        // 逻辑删除，设置删除标识
        LambdaUpdateWrapper<SysMenuEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(SysMenuEntity::getMenuId, childIdList)
                .set(SysMenuEntity::getDelFlag, YesOrNotEnum.Y.getCode());
        this.update(updateWrapper);

        // 删除该菜单下的按钮
        sysMenuButtonService.menuButtonDeleteByMenuId(req.getMenuId());
    }

    @Override
    public List<SysMenuTreeResp> menuListTree(SysMenuReq req) {
        List<SysMenuTreeResp> sysMenuTreeRespList = this.findList(req);
        // 遍历菜单，设置是否是叶子节点属性
        MenuFactory.fillLeafFlag(sysMenuTreeRespList);
        // 将结果集处理成树
        List<SysMenuTreeResp> treeMenus = new DefaultTreeBuildFactory<SysMenuTreeResp>().doTreeBuild(sysMenuTreeRespList);
        // 如果树节点构建失败，则返回平级节点
        if (ObjectUtil.isEmpty(treeMenus)) {
            return sysMenuTreeRespList;
        } else {
            return treeMenus;
        }
    }
//
//    @Override
//    public List<ZTreeNode> layuiSelectParentMenuTreeList() {
//
//        ArrayList<ZTreeNode> zTreeNodes = new ArrayList<>();
//
//        List<SysMenuEntity> allMenus = this.list();
//        for (SysMenuEntity sysMenuEntity : allMenus) {
//            ZTreeNode zTreeNode = new ZTreeNode();
//            zTreeNode.setId(sysMenuEntity.getMenuId());
//            zTreeNode.setpId(sysMenuEntity.getMenuParentId());
//            zTreeNode.setName(sysMenuEntity.getMenuName());
//            zTreeNode.setOpen(false);
//            zTreeNodes.add(zTreeNode);
//        }
//
//        // 创建顶级节点
//        zTreeNodes.add(ZTreeNode.createParent());
//
//        return zTreeNodes;
//    }

    @Override
    public List<SysMenuDropDownTreeResp> menuDropDownTree(SysMenuReq req) {
        List<SysMenuDropDownTreeResp> menuTreeNodeList = CollectionUtil.newArrayList();
        // 添加根节点
        SysMenuDropDownTreeResp rootNode = MenuFactory.createRootNode();
        menuTreeNodeList.add(rootNode);
        // 获取所有菜单
        LambdaQueryWrapper<SysMenuEntity> wrapper = createWrapper(req);
        this.list(wrapper).forEach(sysMenuEntity -> {
            SysMenuDropDownTreeResp menuTreeNode = MenuFactory.parseMenuBaseTreeNode(sysMenuEntity);
            menuTreeNodeList.add(menuTreeNode);
        });
        // -2是根节点的上级
        return new DefaultTreeBuildFactory<SysMenuDropDownTreeResp>("-2").doTreeBuild(menuTreeNodeList);
    }
//
//    @Override
//    public List<SysMenuTreeResp> getLeftMenuList(SysMenuReq sysMenuReq) {
//        // 获取当前已经启用的应用，并且按排序字段排序的
//        List<SysAppDto> sysAppDtoList = sysAppService.getSortedApps();
//        if (CollUtil.isEmpty(sysAppDtoList)) {
//            throw new BusException(ErrorEnum.CANT_FIND_APPS);
//        }
//        // 查询菜单
//        List<String> appCodeList = sysAppDtoList.stream().map(SysAppDto::getAppCode).collect(Collectors.toList());
//        List<SysMenuEntity> currentUserMenuList = this.getCurrentUserMenus(appCodeList);
//        List<SysMenuTreeDto> sysMenuTreeDto =  Convert.convert(new TypeReference<>() {}, currentUserMenuList);
//        // 将菜单按应用编码分类
//        Map<String, List<SysMenuTreeDto>> sortedUserMenus = MenuFactory.sortUserMenusByAppCode(sysMenuTreeDto);
//        // 获取应用名称集合，带顺序
//        List<String> appNames = sysAppDtoList.stream().map(SysAppDto::getAppName).collect(Collectors.toList());
//        return MenuFactory.createTotalMenus(sortedUserMenus, appNames);
//    }
//
//    @Override
//    public List<LayuiMenuAndButtonTreeResponse> getMenuAndButtonTree(SysRoleVo sysRoleVo, Boolean lateralFlag) {
//        List<LayuiMenuAndButtonTreeResponse> menuTreeNodeList = CollectionUtil.newArrayList();
//
//        // 查询未删除的启用的菜单列表
//        LambdaQueryWrapper<SysMenuEntity> menuWrapper = new LambdaQueryWrapper<>();
//        menuWrapper.eq(SysMenuEntity::getStatusFlag, StatusEnum.ENABLE.getCode());
//        menuWrapper.eq(SysMenuEntity::getDelFlag, YesOrNotEnum.N.getCode());
//
//        // 非超级管理员则获取自己拥有的菜单
//        if (!LoginContext.me().getSuperAdminFlag()) {
//            List<Long> menuIdList = getCurrentUserMenuIds();
//            if (!menuIdList.isEmpty()) {
//                menuWrapper.in(SysMenuEntity::getMenuId, menuIdList);
//            }
//        }
//        List<SysMenuEntity> sysMenuEntityList = this.list(menuWrapper);
//
//        // 获取菜单的id集合
//        List<Long> menuList = sysMenuEntityList.parallelStream().map(SysMenuEntity::getId).collect(Collectors.toList());
//
//        // 查询这些菜单对应的所有按钮
//        LambdaQueryWrapper<SysMenuButtonEntity> buttonWrapper = new LambdaQueryWrapper<>();
//        buttonWrapper.eq(SysMenuButtonEntity::getDelFlag, YesOrNotEnum.N.getCode());
//        buttonWrapper.in(SysMenuButtonEntity::getMenuId, menuList);
//        List<SysMenuButtonEntity> sysMenuButtonEntities = sysMenuButtonService.list(buttonWrapper);
//
//        // 把按钮按照菜单id存起来，方便后续操作
//        Map<Long, List<SysMenuButtonEntity>> buttons = new HashMap<>(menuList.size());
//        for (SysMenuButtonEntity menuButton : sysMenuButtonEntities) {
//            List<SysMenuButtonEntity> buttonList = buttons.get(menuButton.getMenuId());
//            if (ObjectUtil.isEmpty(buttonList)) {
//                buttonList = new ArrayList<>();
//                buttons.put(menuButton.getMenuId(), buttonList);
//            }
//            buttonList.add(menuButton);
//        }
//
//        // 查询所有已有的权限
//        // 所有已有的菜单权限
//        List<SysRoleMenuDTO> roleMenuList = roleServiceApi.getRoleMenuList(Collections.singletonList(sysRoleRequest.getRoleId()));
//
//        // 转换成map方便后续处理
//        Map<Long, SysRoleMenuDTO> roleMenuMap = new HashMap<>();
//        for (SysRoleMenuDTO sysRoleMenuResponse : roleMenuList) {
//            roleMenuMap.put(sysRoleMenuResponse.getMenuId(), sysRoleMenuResponse);
//        }
//
//        // 所有的按钮权限
//        List<SysRoleMenuButtonDTO> roleMenuButtonList = roleServiceApi.getRoleMenuButtonList(Collections.singletonList(sysRoleVo.getId()));
//
//        // 转换成map方便后续处理
//        Map<Long, SysRoleMenuButtonDTO> roleMenuButtonMap = new HashMap<>();
//        for (SysRoleMenuButtonDTO buttonResponse : roleMenuButtonList) {
//            roleMenuButtonMap.put(buttonResponse.getButtonId(), buttonResponse);
//        }
//
//        // 组装树结果
//        for (SysMenuEntity sysMenuEntity : sysMenuEntityList) {
//            LayuiMenuAndButtonTreeResponse menuTree = new LayuiMenuAndButtonTreeResponse();
//            menuTree.setId(sysMenuEntity.getId());
//            menuTree.setMenuFlag(true);
//            menuTree.setName(sysMenuEntity.getMenuName());
//            menuTree.setPid(sysMenuEntity.getMenuParentId());
//            // 判断是否已经有了
//            SysRoleMenuDTO roleMenuResponse = roleMenuMap.get(sysMenuEntity.getId());
//            menuTree.setChecked(!ObjectUtil.isEmpty(roleMenuResponse));
//
//            // 处理该菜单的按钮
//            List<SysMenuButtonEntity> menuButtons = buttons.get(sysMenuEntity.getId());
//
//            // 不为空就去处理
//            if (ObjectUtil.isNotEmpty(menuButtons)) {
//                for (SysMenuButtonEntity menuButton : menuButtons) {
//                    LayuiMenuAndButtonTreeResponse buttonTree = new LayuiMenuAndButtonTreeResponse();
//                    buttonTree.setName(menuButton.getButtonName());
//                    buttonTree.setId(menuButton.getId());
//                    buttonTree.setPid(menuButton.getMenuId());
//                    buttonTree.setButtonCode(menuButton.getButtonCode());
//                    buttonTree.setMenuFlag(false);
//                    // 判断是否已经拥有
//                    SysRoleMenuButtonDTO buttonResponse = roleMenuButtonMap.get(menuButton.getId());
//                    if (ObjectUtil.isNotEmpty(buttonResponse)) {
//                        buttonTree.setChecked(true);
//                        menuTree.setChecked(true);
//                    } else {
//                        buttonTree.setChecked(false);
//                    }
//                    // 记录按钮节点
//                    menuTreeNodeList.add(buttonTree);
//                }
//            }
//            // 记录菜单节点
//            menuTreeNodeList.add(menuTree);
//        }
//
//        // 返回结果
//        if (lateralFlag) {
//            return menuTreeNodeList;
//        } else {
//            return new DefaultTreeBuildFactory<LayuiMenuAndButtonTreeResponse>().doTreeBuild(menuTreeNodeList);
//        }
//    }
//
//    @Override
//    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
//    public List<MenuAndButtonTreeResponse> getRoleMenuAndButtons(SysRoleVo sysRoleVo) {
//        // 查询未删除的启用的菜单列表
//        LambdaQueryWrapper<SysMenuEntity> menuWrapper = new LambdaQueryWrapper<>();
//        menuWrapper.eq(SysMenuEntity::getDelFlag, YesOrNotEnum.N.getCode());
//        menuWrapper.eq(SysMenuEntity::getStatusFlag, StatusEnum.ENABLE.getCode());
//
//        // 查询所有菜单列表
//        List<SysMenuEntity> sysMenuEntityList = this.list(menuWrapper);
//
//        // 获取菜单的id集合
//        List<Long> menuIdList = sysMenuEntityList.stream().map(SysMenuEntity::getId).collect(Collectors.toList());
//
//        // 获取角色绑定的菜单的id
//        List<SysRoleMenuDTO> roleMenuList = roleServiceApi.getRoleMenuList(Collections.singletonList(sysRoleVo.getId()));
//
//        // 转化 --->>> 菜单列表自转化为响应的节点类型
//        List<MenuAndButtonTreeResponse> menuAndButtonTreeResponses = AntdMenusFactory.parseMenuAndButtonTreeResponse(sysMenuEntityList, roleMenuList);
//
//        // 查询这些菜单对应的所有按钮
//        LambdaQueryWrapper<SysMenuButtonEntity> buttonWrapper = new LambdaQueryWrapper<>();
//        buttonWrapper.eq(SysMenuButtonEntity::getDelFlag, YesOrNotEnum.N.getCode());
//        buttonWrapper.in(SysMenuButtonEntity::getMenuId, menuIdList);
//        List<SysMenuButtonEntity> buttonList = sysMenuButtonService.list(buttonWrapper);
//
//        // 获取角色绑定的按钮的id
//        List<SysRoleMenuButtonDTO> roleMenuButtonList = roleServiceApi.getRoleMenuButtonList(Collections.singletonList(sysRoleVo.getId()));
//
//        // 转化 --->>> 将这些按钮，分别绑定在各自的菜单上
//        AntdMenusFactory.fillButtons(menuAndButtonTreeResponses, buttonList, roleMenuButtonList);
//
//        // 菜单列表转化为一棵树
//        return new DefaultTreeBuildFactory<MenuAndButtonTreeResponse>().doTreeBuild(menuAndButtonTreeResponses);
//    }
//
//    @Override
//    public List<MenuAndButtonTreeResponse> getRoleBindMenuList(SysRoleVo sysRoleVo) {
//
//        // 获取所有一级菜单，子菜单包含在children内
//        List<SysMenuEntity> sysMenuEntities = totalMenusWithOneLevel(sysRoleVo.getResourceBizType());
//
//        // 获取角色绑定的菜单
//        List<SysRoleMenuDTO> roleMenuList = roleServiceApi.getRoleMenuList(Collections.singletonList(sysRoleVo.getId()));
//
//        // 将组装好的一级菜单和里边的children都转化为响应对象，并填充checked标识
//        return AntdMenusFactory.parseMenuAndButtonTreeResponseWithChildren(sysMenuEntities, roleMenuList);
//    }
//
//    @Override
//    public List<MenuAndButtonTreeResponse> getRoleBindOperateList(SysRoleVo sysRoleVo) {
//
//        // 获取所有一级菜单，子菜单包含在children内
//        List<SysMenuEntity> sysMenuEntities = totalMenusWithOneLevel(sysRoleVo.getResourceBizType());
//
//        // 查询这些菜单对应的所有按钮
//        LambdaQueryWrapper<SysMenuButtonEntity> buttonWrapper = new LambdaQueryWrapper<>();
//        buttonWrapper.eq(SysMenuButtonEntity::getDelFlag, YesOrNotEnum.N.getCode());
//        List<SysMenuButtonEntity> buttonList = sysMenuButtonService.list(buttonWrapper);
//
//        // 将组装好的一级菜单和里边的children都转化为响应对象
//        List<MenuAndButtonTreeResponse> menuAndButtonTreeResponses = AntdMenusFactory.fillButtons(sysMenuEntities, buttonList);
//
//        // 填充checked对象
//        List<SysRoleMenuButtonDTO> roleMenuButtonList = roleServiceApi.getRoleMenuButtonList(Collections.singletonList(sysRoleVo.getId()));
//        return AntdMenusFactory.fillButtonsChecked(menuAndButtonTreeResponses, roleMenuButtonList);
//    }
//
//    @Override
//    public List<Long> getTotalMenuIdList(AntdvFrontTypeEnum antdvFrontTypeEnum) {
//
//        // 查询所有菜单列表，根据前台传递参数，可选择前台还是后台菜单
//        LambdaQueryWrapper<SysMenuEntity> menuWrapper = new LambdaQueryWrapper<>();
//        menuWrapper.select(SysMenuEntity::getId);
//
//        menuWrapper.eq(SysMenuEntity::getDelFlag, YesOrNotEnum.N.getCode());
//        menuWrapper.eq(SysMenuEntity::getStatusFlag, StatusEnum.ENABLE.getCode());
//
//        if (antdvFrontTypeEnum != null) {
//            menuWrapper.nested(i -> i.eq(SysMenuEntity::getAntdvFrontType, antdvFrontTypeEnum.getCode()).or().eq(SysMenuEntity::getAntdvFrontType, AntdvFrontTypeEnum.TOTAL_SHOW.getCode()));
//        }
//
//        List<SysMenuEntity> sysMenuEntityList = this.list(menuWrapper);
//        return sysMenuEntityList.stream().map(SysMenuEntity::getId).collect(Collectors.toList());
//    }
//
//    @Override
//    public List<SysMenuButtonDTO> getTotalMenuButtonIdList(AntdvFrontTypeEnum antdvFrontTypeEnum) {
//
//        List<Long> totalMenuIdList = this.getTotalMenuIdList(antdvFrontTypeEnum);
//
//        if (ObjectUtil.isEmpty(totalMenuIdList)) {
//            return new ArrayList<>();
//        }
//
//        // 获取所有按钮id集合
//        LambdaQueryWrapper<SysMenuButtonEntity> wrapper = new LambdaQueryWrapper<>();
//        wrapper.select(SysMenuButtonEntity::getId, SysMenuButtonEntity::getButtonCode);
//        wrapper.eq(SysMenuButtonEntity::getDelFlag, YesOrNotEnum.N.getCode());
//        wrapper.in(SysMenuButtonEntity::getMenuId, totalMenuIdList);
//
//        List<SysMenuButtonEntity> list = this.sysMenuButtonService.list(wrapper);
//
//        ArrayList<SysMenuButtonDTO> menuButtonDTOS = new ArrayList<>();
//        for (SysMenuButtonEntity sysMenuButtonEntity : list) {
//            SysMenuButtonDTO sysMenuButtonDTO = new SysMenuButtonDTO();
//            sysMenuButtonDTO.setButtonId(sysMenuButtonEntity.getId());
//            sysMenuButtonDTO.setButtonCode(sysMenuButtonEntity.getButtonCode());
//            menuButtonDTOS.add(sysMenuButtonDTO);
//        }
//        return menuButtonDTOS;
//    }
//
//    @Override
//    public AntdvFrontTypeEnum getUserMenuType(List<Long> menuIds) {
//
//        // 用户没有菜单，默认只返回前台菜单类型
//        if (ObjectUtil.isEmpty(menuIds)) {
//            return AntdvFrontTypeEnum.FRONT;
//        }
//
//        // 判断菜单中有多少种类的菜单
//        LambdaQueryWrapper<SysMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.select(SysMenuEntity::getAntdvFrontType);
//        queryWrapper.in(SysMenuEntity::getId, menuIds);
//        List<SysMenuEntity> sysMenuEntityList = this.list(queryWrapper);
//
//        // 获取各类菜单的数量
//        long frontTypes = sysMenuEntityList.stream().filter(sysMenu -> AntdvFrontTypeEnum.FRONT.getCode().equals(sysMenu.getAntdvFrontType())).count();
//        long backendTypes = sysMenuEntityList.stream().filter(sysMenu -> AntdvFrontTypeEnum.BACKEND.getCode().equals(sysMenu.getAntdvFrontType())).count();
//
//        if (frontTypes > 0 && backendTypes > 0) {
//            return AntdvFrontTypeEnum.TOTAL_SHOW;
//        } else if (frontTypes > 0) {
//            return AntdvFrontTypeEnum.FRONT;
//        } else if (backendTypes > 0) {
//            return AntdvFrontTypeEnum.BACKEND;
//        }
//
//        return AntdvFrontTypeEnum.FRONT;
//    }

    //    @Override
    public List<SysMenuEntity> getCurrentUserMenus(List<String> appCodeList) {
        LambdaQueryWrapper<SysMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMenuEntity::getStatusFlag, StatusEnum.ENABLE.getCode())
                .eq(SysMenuEntity::getDelFlag, YesOrNotEnum.N.getCode())
                .eq(CollUtil.isNotEmpty(appCodeList), SysMenuEntity::getAppCode, appCodeList)
                .orderByAsc(SysMenuEntity::getMenuSort);
        if (LoginContext.me().getSuperAdminFlag()) {
            return this.list(queryWrapper);
        }

        List<Long> menuIdList = getCurrentUserMenuIds();
        if (menuIdList.isEmpty()) {
            return Collections.emptyList();
        }
        queryWrapper.in(SysMenuEntity::getMenuId, menuIdList);
        return this.list(queryWrapper);
    }

    @Override
    public boolean hasMenu(String appCode) {
        SysMenuReq sysMenuReq = new SysMenuReq();
        sysMenuReq.setAppCode(appCode);
        LambdaQueryWrapper<SysMenuEntity> wrapper = this.createWrapper(sysMenuReq);

        List<SysMenuEntity> list = this.list(wrapper);
        return !list.isEmpty();
    }
//
//    @Override
//    public List<String> getUserAppCodeList() {
//
//        LambdaQueryWrapper<SysMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.select(SysMenuEntity::getAppCode);
//        queryWrapper.groupBy(SysMenuEntity::getAppCode);
//
//        // 非超级管理员获取自己的菜单
//        if (!LoginContext.me().getSuperAdminFlag()) {
//            List<Long> currentUserMenuIds = this.getCurrentUserMenuIds();
//            queryWrapper.in(SysMenuEntity::getMenuId, currentUserMenuIds);
//        }
//
//        List<SysMenuEntity> list = this.list(queryWrapper);
//        return list.stream().map(SysMenuEntity::getAppCode).collect(Collectors.toList());
//    }
//
//    @Override
//    public Set<Long> getMenuAllParentMenuId(Set<Long> menuIds) {
//        Set<Long> parentMenuIds = new HashSet<>();
//
//        // 查询所有菜单信息
//        List<SysMenuEntity> sysMenuEntities = this.listByIds(menuIds);
//        if (ObjectUtil.isEmpty(sysMenuEntities)) {
//            return parentMenuIds;
//        }
//
//        // 获取所有父菜单ID
//        for (SysMenuEntity sysMenuEntity : sysMenuEntities) {
//            String menuPids = sysMenuEntity.getMenuPids().replaceAll("\\[", "").replaceAll("\\]", "");
//            String[] ids = menuPids.split(SymbolEnum.COMMA.getValue());
//            for (String id : ids) {
//                parentMenuIds.add(Long.parseLong(id));
//            }
//        }
//
//        return parentMenuIds;
//    }
//
//    @Override
//    public String getMenuButtonCodeByButtonId(Long buttonId) {
//        SysMenuButtonEntity sysMenuButtonEntity = this.sysMenuButtonService.getById(buttonId);
//        if (sysMenuButtonEntity != null) {
//            return sysMenuButtonEntity.getButtonCode();
//        } else {
//            return "";
//        }
//    }
//
    @Override
    public List<String> getResourceCodesByBusinessId(List<Long> businessIds) {
        if (ObjectUtil.isEmpty(businessIds)) {
            return new ArrayList<>();
        }

        LambdaQueryWrapper<SysMenuResourceEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SysMenuResourceEntity::getBusinessId, businessIds);
        wrapper.select(SysMenuResourceEntity::getResourceCode);
        List<SysMenuResourceEntity> list = sysMenuResourceService.list(wrapper);

        return list.stream().map(SysMenuResourceEntity::getResourceCode).collect(Collectors.toList());
    }
//
//    @Override
//    public List<IndexMenuInfo> buildAuthorities(Integer menuFrontType, Boolean devopsFlag) {
//
//        // 不分离应用查询菜单
//        List<SysAppResult> sortedApps = appServiceApi.getSortedApps(devopsFlag);
//        List<String> appCodes = sortedApps.stream().map(SysAppResult::getAppCode).collect(Collectors.toList());
//        List<SysMenuEntity> currentUserMenus = this.getCurrentUserMenus(appCodes, menuFrontType);
//
//        // 获取当前激活的应用
//        List<String> appNames = sortedApps.stream().map(SysAppResult::getAppName).collect(Collectors.toList());
//
//        // 将菜单按应用编码分类，激活的应用放在最前边
//        Map<String, List<SysMenuEntity>> sortedUserMenus = AntdMenusFactory.sortUserMenusByAppCode(currentUserMenus);
//
//        return Antdv3MenusFactory.createTotalMenus(sortedUserMenus, appNames);
//    }

    /**
     * 获取系统菜单
     *
     * @author GD
     * @since 2020/3/27 9:13
     */
    private SysMenuEntity querySysMenu(SysMenuReq req) {
        SysMenuEntity sysMenuEntity = this.getById(req.getMenuId());
        if (ObjectUtil.isNull(sysMenuEntity) || YesOrNotEnum.Y.getCode().equals(sysMenuEntity.getDelFlag())) {
            throw new BusException(ErrorEnum.MENU_NOT_EXIST);
        }
        return sysMenuEntity;
    }

    /**
     * 创建pids的值
     * <p>
     * 如果pid是0顶级节点，pids就是 [-1],
     * <p>
     * 如果pid不是顶级节点，pids就是父菜单的pids + [pid] + ,
     *
     * @author GD, stylefeng
     * @since 2020/3/26 11:28
     */
    private String createPids(Long pid) {
        if (pid == -1L) {
            return SymbolEnum.LEFT_SQUARE_BRACKETS.getValue() + -1L + SymbolEnum.RIGHT_SQUARE_BRACKETS.getValue() + SymbolEnum.COMMA.getValue();
        } else {
            //获取父菜单
            SysMenuReq sysMenuReq = new SysMenuReq();
            sysMenuReq.setMenuId(pid);
            SysMenuEntity parentMenu = this.querySysMenu(sysMenuReq);
            // 组装pids(父级集合+[+pid+]+,)
            return parentMenu.getMenuPids() + SymbolEnum.LEFT_SQUARE_BRACKETS.getValue() + pid + SymbolEnum.RIGHT_SQUARE_BRACKETS.getValue() + SymbolEnum.COMMA.getValue();
        }
    }

    /**
     * 创建查询条件wrapper
     *
     * @author GD
     * @since 2020/11/6 10:16
     */
    private LambdaQueryWrapper<SysMenuEntity> createWrapper(SysMenuReq req) {
        LambdaQueryWrapper<SysMenuEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysMenuEntity::getDelFlag, YesOrNotEnum.N.getCode())
                .orderByAsc(SysMenuEntity::getAppCode, SysMenuEntity::getMenuSort);

        if (ObjectUtil.isEmpty(req)) {
            return wrapper;
        }
        wrapper.eq(ObjectUtil.isNotEmpty(req.getAppCode()), SysMenuEntity::getAppCode, req.getAppCode())
                .like(ObjectUtil.isNotEmpty(req.getMenuName()), SysMenuEntity::getMenuName, req.getMenuName())
                .like(ObjectUtil.isNotEmpty(req.getMenuCode()), SysMenuEntity::getMenuCode, req.getMenuCode())
                .orderByAsc(SysMenuEntity::getAppCode, SysMenuEntity::getMenuSort);
        return wrapper;
    }

    /**
     * 获取当前用户的菜单id集合
     *
     * @author GD
     * @since 2020/11/22 23:15
     */
    private List<Long> getCurrentUserMenuIds() {
        // TODO: 动态获取当前登录人
//        LoginUser loginUser = LoginContext.me().getLoginUser();
//        List<Long> roleIdList = loginUser.getSimpleRoleInfoList().stream().map(SimpleRoleInfo::getRoleId).toList();
        List<Long> roleIdList = new ArrayList<>();
        roleIdList.add(1339550467939639303L);
        roleIdList.add(1339550467939639304L);

        if (ObjectUtil.isEmpty(roleIdList)) {
            return CollectionUtil.newArrayList();
        }

        // 获取角色拥有的菜单id集合
        List<Long> menuIdList = sysRoleService.getMenuIdsByRoleIds(roleIdList);
        if (ObjectUtil.isEmpty(menuIdList)) {
            return CollectionUtil.newArrayList();
        }

        return menuIdList;
    }

    /**
     * 更新子节点以及子节点的子节点的appCode和层级关系（pids）
     *
     * @author GD
     * @since 2020/11/23 22:05
     */
    private String updateChildrenAppAndLevel(SysMenuReq newMenu, SysMenuEntity oldMenu) {
        // 本菜单旧的pids
        Long oldPid = oldMenu.getMenuParentId();
        String oldPids = oldMenu.getMenuPids();
        // 生成新的pid和pid
        Long newPid = newMenu.getMenuParentId();
        String newPids = this.createPids(newMenu.getMenuParentId());

        // 是否更新子应用的标识
        boolean updateSubAppsFlag = false;
        // 是否更新子节点的pids的标识
        boolean updateSubPidsFlag = false;

        // 如果应用有变化，不能把非一级菜单转移应用
        if (!newMenu.getAppCode().equals(oldMenu.getAppCode())) {
            if (oldPid != -1L) {
                throw new ServiceException(ErrorEnum.CANT_MOVE_APP);
            }
            updateSubAppsFlag = true;
        }
        // 父节点有变化
        if (!newPid.equals(oldPid)) {
            updateSubPidsFlag = true;
        }
        // 开始更新所有子节点的配置
        if (updateSubAppsFlag || updateSubPidsFlag) {
            // 查找所有叶子节点，包含子节点的子节点
            LambdaQueryWrapper<SysMenuEntity> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.like(SysMenuEntity::getMenuPids, oldMenu.getMenuId());
            List<SysMenuEntity> list = this.list(queryWrapper);
            // 更新所有子节点的应用为当前菜单的应用
            if (ObjectUtil.isNotEmpty(list)) {
                // 更新所有子节点的application
                if (updateSubAppsFlag) {
                    list.forEach(child -> child.setAppCode(newMenu.getAppCode()));
                }
                // 更新所有子节点的pids
                if (updateSubPidsFlag) {
                    list.forEach(child -> {
                        // 子节点pids组成 = 当前菜单新pids + 当前菜单id + 子节点自己的pids后缀
                        String oldParentCodesPrefix = oldPids + SymbolEnum.LEFT_SQUARE_BRACKETS.getValue() + oldMenu.getMenuId() + SymbolEnum.RIGHT_SQUARE_BRACKETS.getValue() + SymbolEnum.COMMA.getValue();
                        String oldParentCodesSuffix = child.getMenuPids().substring(oldParentCodesPrefix.length());
                        String menuParentCodes =
                                newPids + SymbolEnum.LEFT_SQUARE_BRACKETS.getValue() + oldMenu.getMenuId() + SymbolEnum.RIGHT_SQUARE_BRACKETS.getValue() + SymbolEnum.COMMA.getValue() + oldParentCodesSuffix;
                        child.setMenuPids(menuParentCodes);
                    });
                }
                this.updateBatchById(list);
            }
        }
        return newPids;
    }
//
//    /**
//     * 获取所有的菜单，以一级菜单的形式展示
//     *
//     * @param antdvFrontType 菜单是前台显示还是后台显示
//     * @author GD
//     * @since 2022/9/28 17:46
//     */
//    private List<SysMenuEntity> totalMenusWithOneLevel(Integer antdvFrontType) {
//        // 查询所有菜单列表，根据前台传递参数，可选择前台还是后台菜单
//        LambdaQueryWrapper<SysMenuEntity> menuWrapper = new LambdaQueryWrapper<>();
//        menuWrapper.eq(SysMenuEntity::getDelFlag, YesOrNotEnum.N.getCode());
//        menuWrapper.eq(SysMenuEntity::getStatusFlag, StatusEnum.ENABLE.getCode());
//
//        // 查询所有指定类型的菜单
//        if (antdvFrontType != null) {
//            menuWrapper.nested(i -> i.eq(SysMenuEntity::getAntdvFrontType, antdvFrontType).or().eq(SysMenuEntity::getAntdvFrontType, AntdvFrontTypeEnum.TOTAL_SHOW.getCode()));
//        }
//
//        List<SysMenuEntity> sysMenuEntityList = this.list(menuWrapper);
//
//        // 将所有节点转化成树结构，整体只要两级结构，一级是一级菜单，第二级是所有以下菜单
//        Map<Long, SysMenuEntity> firstLevelMenus = new HashMap<>();
//
//        // 找到所有第一级的菜单
//        for (SysMenuEntity sysMenuEntity : sysMenuEntityList) {
//            if (TreeConstants.DEFAULT_PARENT_ID.equals(sysMenuEntity.getMenuParentId())) {
//                firstLevelMenus.put(sysMenuEntity.getMenuId(), sysMenuEntity);
//            }
//        }
//
//        // 找到所有二级和以下菜单，并添加到一级菜单以下
//        for (Map.Entry<Long, SysMenuEntity> menuEntry : firstLevelMenus.entrySet()) {
//            SysMenuEntity firstLevelMenuItem = menuEntry.getValue();
//            List<SysMenuEntity> children = firstLevelMenuItem.getChildren();
//            if (children == null) {
//                children = new ArrayList<>();
//                firstLevelMenuItem.setChildren(children);
//            }
//            for (SysMenuEntity sysMenuEntity : sysMenuEntityList) {
//                if (sysMenuEntity.getMenuPids().contains("[" + firstLevelMenuItem.getMenuId() + "]")) {
//                    children.add(sysMenuEntity);
//                }
//            }
//        }
//
//        return ListUtil.toList(firstLevelMenus.values());
//    }

    /**
     * 校验菜单，是否在通应用下重复
     *
     * @author GD
     * @since 2023/3/14 14:37
     */
    private void validateMenu(SysMenuReq req) {
        SysMenuReq param = new SysMenuReq();
        param.setAppCode(req.getAppCode());
        param.setMenuName(req.getMenuName());

        // 查询应用编码下是否存在该名称的菜单
        List<SysMenuTreeResp> sysMenuTreeRespList = this.findList(param);
        if (CollUtil.isNotEmpty(sysMenuTreeRespList)) {
            boolean haveSameFlag = true;
            // 如果请求参数中有菜单id，则为编辑菜单操作，可以和本菜单重复
            for (SysMenuTreeResp sysMenuTreeResp : sysMenuTreeRespList) {
                if (sysMenuTreeResp.getMenuId().equals(req.getMenuId())) {
                    haveSameFlag = false;
                    break;
                }
            }
            if (haveSameFlag) {
                throw new BusException(ErrorEnum.TABLE_UNIQUE_VALIDATE_ERROR);
            }
        }
    }

    /**
     * 校验菜单，是否在通应用下重复
     *
     * @author GD
     * @since 2023/3/14 14:37
     */
    private List<SysMenuTreeResp> findList(SysMenuReq req) {
        LambdaQueryWrapper<SysMenuEntity> wrapper = createWrapper(req);
        List<SysMenuEntity> sysMenuEntityList = this.list(wrapper);
        List<SysMenuTreeResp> sysMenuTreeList = Convert.convert(new TypeReference<>() {
        }, sysMenuEntityList);

        // 应用编码转化为应用名称
        HashMap<String, String> appCodeName = new HashMap<>();
        Set<String> appCodeSet = sysMenuTreeList.stream().map(SysMenuTreeResp::getAppCode).collect(Collectors.toSet());
        for (String appCode : appCodeSet) {
            String appName = sysAppService.getAppNameByAppCode(appCode);
            appCodeName.put(appCode, appName);
        }
        for (SysMenuTreeResp sysMenuTreeResp : sysMenuTreeList) {
            sysMenuTreeResp.setAppName(appCodeName.get(sysMenuTreeResp.getAppCode()));
        }
        return sysMenuTreeList;
    }

}
